package com.enbatis.mybatisplugs.controller;

import com.enbatis.mybatisplugs.base.Account;
import com.enbatis.mybatisplugs.base.BaseController;
import com.enbatis.mybatisplugs.commons.sql.Wrapper;
import com.enbatis.mybatisplugs.commons.utils.CodeMsg;
import com.enbatis.mybatisplugs.commons.utils.MD5Util;
import com.enbatis.mybatisplugs.commons.utils.ResultReturn;

//import com.enbatis.mybatisplugs.component.WebSocket;
import com.enbatis.mybatisplugs.entity.LoginLog;
import com.enbatis.mybatisplugs.entity.SysUser;
import com.enbatis.mybatisplugs.entity.dto.ImgVcode;
import com.enbatis.mybatisplugs.entity.vo.SysUserVO;
import com.enbatis.mybatisplugs.service.LoginLogService;
import com.enbatis.mybatisplugs.service.SysUserService;
import com.enbatis.mybatisplugs.toolkit.CaptchaUtil;
import com.enbatis.mybatisplugs.toolkit.CusAccessObjectUtil;
import com.enbatis.mybatisplugs.toolkit.LoginCacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;


@Controller
@RequestMapping("v1/login")
@Slf4j
public class LoginController extends BaseController {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private LoginLogService loginLogService;


//    @Autowired
//    private WebSocket webSocket;

    @Value("${service.domain}")
    private String domain;

    @RequestMapping("/test")
    public String test(Model model){

        model.addAttribute("name","王卫东是");

        return "test";
    }


    @PostMapping("/login12")
    public ResultReturn login(SysUserVO user){
        String ip=  CusAccessObjectUtil.getIpFromRequest(request);
       String username =request.getParameter("username");
       String code =request.getParameter("code");
       String vcode =request.getParameter("vcode");
       if (StringUtils.isBlank(vcode)){
           return failed(CodeMsg.LOGIN_V_CODE_BLANK);
       }

        if (!code.equalsIgnoreCase(MD5Util.getSalt(vcode.toLowerCase()))){
            return failed(CodeMsg.LOGIN_V_CODE_WRONG);
        }
        if (null== LoginCacheUtil.mapVCode.get(code)){
            return failed(CodeMsg.LOGIN_V_CODE_OVER);
        }

        LoginCacheUtil.mapVCode.remove(code);

       String password= MD5Util.generate(request.getParameter("password"));

        List<SysUser> list= sysUserService.list(new Wrapper<>(new SysUser()).eq("username",username).eq("password",password));
        Optional<SysUser> first= list.stream().filter(dbUser->dbUser.getUsername().equals(user.getUsername())&&dbUser.getPassword().equals(password)).findFirst();

        if (first.isPresent()){
            user.setUsername(username);
            String token= UUID.randomUUID().toString();
            HttpSession session=request.getSession();
            session.setAttribute("TOKEN",user);
            Cookie cookie=new Cookie("TOKEN",token);
            response.addHeader("TOKEN",token);
            cookie.setDomain(domain);
            cookie.setPath("/");
            response.addCookie(cookie);
            Account account=new Account();
            account.setId(first.get().getId());
            account.setUsername(first.get().getUsername());
            account.setCompanyId(first.get().getCompanyId());
            LoginCacheUtil.loginUser.put(token,account);

            try {
                  LoginLog log=new LoginLog();
                log.setIp(ip);
                log.setUserId(account.getId());
                log.setUsername(account.getUsername());
                log.setCtime(new Date());
                loginLogService.insert(log);
            }catch (Exception e){
               log.error("登录失败"+e.getMessage(),e);
            }

            return  success("/");

        }else{
            return failed(CodeMsg.LOGIN_USER_PSD_ERROR);
        }

    }


    @RequestMapping("/add")
    public String add(){
        return "/user/add";
    }





    @RequestMapping("/update")
    public String update(){
        return "/user/update";
    }


    @RequestMapping("/tologin")
    public ModelAndView toLogin(){
        ModelAndView modelAndView = new ModelAndView("login");
        return modelAndView;
    }


    @RequestMapping("/unAuth")
    public String unAuth(){
        return "unAuth";
    }



    @GetMapping("/user_info")
    public ResultReturn<Account> test(){
        return success(getAccount());
    }

    @PostMapping("/login_out")
    public ResultReturn loginOut(){
         Cookie [] cookies=request.getCookies();
         if (null!=cookies&&cookies.length>0){
             for (Cookie cookie:cookies) {
                 String value=cookie.getValue();
                 if ( LoginCacheUtil.loginUser.containsKey(value)){
                     LoginCacheUtil.loginUser.remove(value);
                   return success(true) ;
                 }

             }
         }
         return failed(CodeMsg.SERVER_EXCEPTION);
    }


//    @Autowired
//    private HelloSender helloSender;
//    @GetMapping("/rabbit_mq_hello")
//    public String hello() throws Exception {
//        helloSender.send();
//        return "";
//    }
@GetMapping("/createCode")
public ResultReturn createCode(HttpServletRequest request, HttpServletResponse response) throws IOException

    {
        // 通知浏览器不要缓存
        response.setHeader("Expires", "-1");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "-1");
        CaptchaUtil util = CaptchaUtil.Instance();
        // 将验证码输入到session中，用来验证
        String code = util.getString();
        request.getSession().setAttribute("code", code);
        LoginCacheUtil.mapVCode.put(MD5Util.getSalt(code.toLowerCase()),code);
        // 输出打web页面

        ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
        ImageIO.write(util.getImage(), "jpg", baos);//写入流中
        byte[] bytes = baos.toByteArray();//转换成字节
        BASE64Encoder encoder = new BASE64Encoder();
        String png_base64 =  encoder.encodeBuffer(bytes).trim();//转换成base64串
        png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除
        ImgVcode vcode =new ImgVcode();
        vcode.setCode(MD5Util.getSalt(code.toLowerCase()));
        vcode.setUrl(png_base64);
        return success(vcode);

}


    @GetMapping("/sendAllWebSocket")
    public String testWc() {
        String text="你们好！这是websocket群体发送！";
//        webSocket.sendAllMessage(text);
        return text;
    }

    @GetMapping("/sendOneWebSocket/{userName}")
    public String sendOneWebSocket(@PathVariable("userName") String userName) {
        String text=userName+" 你好！ 这是websocket单人发送！";
//        webSocket.sendOneMessage(userName,text);
        return text;
    }


//    @GetMapping("/get_online_count")
//    public ResultReturn getOnlineCount() {
////      return success(WebSocket.getOnlineCount());
//
//    }




    @RequestMapping("/login")
    public String login(String name,String password,Model model){
        password=  MD5Util.getSalt(password);

        Subject subject= SecurityUtils.getSubject();


        UsernamePasswordToken token=new UsernamePasswordToken(name,password);


        try {
            subject.login(token);
        }catch (UnknownAccountException e){
            model.addAttribute("msg","用户名不存在");
            return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }

        return "redirect:test";
    }



    @RequiresRoles("admin")
    @GetMapping("/admin")
    public String admin() {
        return "admin success!";
    }

    @RequiresPermissions("query")
    @GetMapping("/index")
    public String index() {
        return "index success!";
    }

    @RequiresPermissions("add")
    @GetMapping("/add_sh")
    public String addSh() {
        return "add success!";
    }



}
